﻿using System.Collections.Generic;
using System.Linq;
using Styx;
using Styx.CommonBot;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWCache;
using Styx.WoWInternals.WoWObjects;

namespace FarmerJoe.Helpers
{
    static class Pets
    {
        public static LocalPlayer Me { get { return StyxWoW.Me; } }
        public static WoWUnit CT { get { return Me.CurrentTarget; } }
        private static readonly List<WoWPetSpell> PetSpells = new List<WoWPetSpell>();
        private static ulong _petGUID;

        public static void CastPetAction(string action)
        {
            UpdatePetSpells();
            WoWPetSpell spell = PetSpells.FirstOrDefault(p => p.ToString() == action);
            if (spell == null) return;

            Logging.Log.Write(string.Format("[Pet] Casting {0}", action));
            Lua.DoString("CastPetAction({0})", spell.ActionBarIndex + 1);
        }

        public static void CastPetAction(string action, WoWUnit onUnit)
        {
            UpdatePetSpells();
            WoWPetSpell spell = PetSpells.FirstOrDefault(p => p.ToString() == action);
            if (spell == null) return;

            Logging.Log.Write(string.Format("[Pet] Casting {0} on {1}", action, onUnit.SafeName()));
            StyxWoW.Me.SetFocus(onUnit);
            Lua.DoString("CastPetAction({0}, 'focus')", spell.ActionBarIndex + 1);
            StyxWoW.Me.SetFocus(0);
        }

        public static bool CanCastPetAction(string action)
        {
            UpdatePetSpells();

            WoWPetSpell petAction = PetSpells.FirstOrDefault(p => p.ToString() == action);
            return petAction != null && petAction.Spell != null && !petAction.Spell.Cooldown;
        }

        private static void UpdatePetSpells()
        {
            if (!Timers.SpellOkToCast("PetSpells", 500)) return;
            if (!Me.GotAlivePet) return;
            if (_petGUID == Me.Pet.Guid) return;

            _petGUID = Me.Pet.Guid;
            PetSpells.Clear();
            PetSpells.AddRange(StyxWoW.Me.PetSpells);
            Timers.Reset("PetSpells");

        }

        public static Composite DefendMe()
        {
            return new Action(ret=>
                                  {
                                      // No pet? Bail out now. 
                                      if (!Me.GotAlivePet) return RunStatus.Failure;
                                      if (Me.InVehicle) return RunStatus.Failure;
                                      
                                      WoWUnit pet = Me.Pet;
                                      //WoWUnit PCT = Me.Pet.CurrentTarget;

                                      // Pet is attacking something it should? All is good so bail out now. 
                                      if (pet.GotTarget && pet.CurrentTarget.CurrentTargetGuid == Me.Guid) return RunStatus.Failure;
                                      if (!Timers.SpellOkToCast("Pet Defender",500))return RunStatus.Failure;

                                      // Pet doesn't have a target? Give it something to attack.
                                      if (!pet.GotTarget && Me.GotTarget)
                                      {
                                          CastPetAction("Attack");
                                          Timers.Reset("Pet Defender");
                                          return RunStatus.Failure;
                                      }

                                      // Something attacking me and not the pet? Set the pet on it. 
                                      WoWUnit target = null;
                                      foreach (WoWUnit mob in Targeting.Instance.TargetList)
                                      {
                                          if (mob.HasAura("Scatter Shot")) continue;
                                          if (mob.HasAura("Wyvern Sting")) continue;
                                          if (mob.HasAura("Freezing Trap")) continue;
                                          if (mob.CurrentTargetGuid == Me.Guid && Me.Pet.CurrentTargetGuid != mob.Guid)
                                          {
                                              target = mob;
                                              break;
                                          }
                                      }

                                      if (target == null) return RunStatus.Failure;

                                      Logging.Log.Write(string.Format("We have aggro from {0}, sending pet to attack it", target.SafeName()));
                                      CastPetAction("Attack", target);
                                      Timers.Reset("Pet Defender");

                                      // Always do this as we want to continue with our normal DPS
                                      return RunStatus.Failure;
                                  });
        }


        public enum PetType
        {
            // These are CreatureFamily IDs. See 'CurrentPet' for usage.
            None = 0,
            Imp = 23,
            Felguard = 29,
            Voidwalker = 16,
            Felhunter = 15,
            Succubus = 17,

            WrathGuard = 104,
            Shivarra = 102,
            Observer = 103,
            VoidLord = 101,
            FelImp = 100,
        }
        public static PetType CurrentPetType
        {
            get
            {
                WoWUnit myPet = StyxWoW.Me.Pet;
                if (myPet == null) return PetType.None;

                WoWCache.CreatureCacheEntry c;
                myPet.GetCachedInfo(out c);

                //Logging.Log.Write(c.ToString());
                return (PetType)c.FamilyID;
            }
        }
       
    }
}
